Repository navigation
Action the review of the agent instruction files - #7347
Conversation
Separate "never import *" from the __all__ rule, and drop the ban on conditional imports in a package __init__.py. The ban sat under Greppability, where it does not belong: a try-wrapped import of a verbatim name greps perfectly well. It also contradicted the tree, where iris_grib and iris.fileformats.zarr both defer an optional dependency's import. Record that indexing does not shrink a Dask graph. A slice still references every chunk of its source, and is culled only at compute. State the purposes of a docstring, a comment and a module docstring at the head of the section that governs all three. Replace the guard-clause advice with a single-exit rule. Nearly every function in lib/iris that contains a return has exactly one, so the old wording argued against the surrounding code. Delete the prose describing the sphinx-needs item a public module docstring carries. The check_docs_page_metadata hook enforces it, and names the expected type, the line limit and the missing tag when it fails. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A doctest asserts real output, so a change anywhere in the library or the user guide can break one. Nothing in the pytest suite covers them, so the previous rule - run them only if you edited a >>> example - left those breakages to CI. Exempt only changes confined to lib/iris/tests/ or to changelog/, which cannot reach a doctest. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## brownfield #7347 +/- ##
===========================================
Coverage 91.03% 91.03%
===========================================
Files 106 106
Lines 27148 27148
Branches 4961 4961
===========================================
Hits 24715 24715
Misses 1677 1677
Partials 756 756 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
A module docstring is the only prose read on every visit to a module and reviewed in the diff, which makes it the right home for subsystem explanation. Sphinx publishes it, so prose written for a maintainer arrives in front of a user. This directive drops its content instead, leaving it in the file and off the page. Built on docutils and sphinx alone, so it adds no dependency. The content is never parsed, which makes broken markup and unbalanced doctest prompts safe to write and keeps the doctest builder away from them. Misspelling the name stops the build, because make html runs with -W, and the content does not render on the way out. A plain reST comment fails the other way: dedent one line and the prose is silently published. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Names the block in the three places lib/iris/AGENTS.md already sends maintainer-facing prose: the summary of which channel serves which reader, the brevity rule that sorts a sentence by who it is for, and the home for a surprise no test can pin. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sixteen module docstrings carry maintainer-facing prose - design rationale, traps, invariants, coupling - and each gains a one-line todo at the point the maintainer-notes block will go. Converting them is a separate change. The prose has to be read and sorted, and several of these files are under active development, so a wide diff here would conflict with work in flight for no gain. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Three of the removed sentences were said twice. That inline comments scatter an argument, and that a companion Markdown file rots unseen, are both Fast Rule 7. That misspelling the directive fails the build is in the directive's own module docstring. lib/iris/AGENTS.md now fits the 300-line cap its meta-instruction sets, which it did not before. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
stephenworsley
left a comment
There was a problem hiding this comment.
Review covers the AGENTS.md files. I'm happy with the idea of the maintainer notes.
Seventeen module docstrings now split by reader. What a caller needs stays on the page; design rationale, traps, invariants and coupling move into a maintainer-notes block that Sphinx drops. Two of the seventeen are the saving modules added by SciTools#7346, which never carried a marker. iris.io.format_picker loses its marker without gaining a block. Its docstring is a usage tutorial throughout, so it was marked on length rather than on content, and nothing in it is written for a maintainer. Two corrections made in passing, both to text that was being moved anyway. iris.fileformats.zarr._dataset announced three things about Zarr and then listed four. iris.fileformats.cf pointed at "the plan, section 8.4"; section 8 of the design document is Risks and has no subsections, so that resolved to nothing and is dropped. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Session-Id: 76a82181-7fe1-4063-9fd7-deb10fb0d658
stephenworsley
left a comment
There was a problem hiding this comment.
Review covers the module docstrings.
The non-atomic clobber behind the "w-" default is a data-loss warning, not a rationale: a user choosing mode="w" needs to know an interrupted Zarr clobber destroys the old store without completing the new. iris.fileformats.netcdf.loader had one thought split across the boundary. What is left in the module and what moved to the CF loader is one statement, so it goes back whole, into the block. Naming only the netCDF saver implied it was the only one; there are two public _CFSaver subclasses. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Session-Id: ee18e927-ba60-4705-aee1-029036b34706
The run-before-finishing rule keeps one clause of why and drops the rest. The clause earns its place: without it an agent reasons that its change cannot reach a doctest and skips the run, which is the rule this replaced. The checklist item said a doctest you never looked at "is the one that breaks", which implies one you have looked at is already safe. It now states what is true instead: nothing in the pytest suite covers them. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Session-Id: ee18e927-ba60-4705-aee1-029036b34706
stephenworsley
left a comment
There was a problem hiding this comment.
I think this is mergeable now.
One thing I'd like to highlight here is my comment on the structure of the API docs for zarr.__init__ being less clear than we would like it. This is out of scope for this PR and at the moment is a tradeoff for the sake of making zarr an optional dependency. It's not necessarily a blocker to merging this into main but it's worth recording as a concern.
(posted by Claude Opus)
Description
Adds a
maintainer-notesSphinx directive, and actions pp-mo's review of the agent instruction files added in #7309. The directive gives module docstrings somewhere to put prose written for a maintainer, so it stays in the file and never reaches the published API page — which is what made "put the explanation in the module docstring" a hard sell. No shipped behaviour changes, so the risk is that a rule now says the wrong thing to future agents, or that the directive hides less than it claims.The directive is built on
docutilsandsphinxalone, so it adds no dependency. Its content is never parsed, which means broken markup and unbalanced>>>prompts inside it cannot break a docs build, and the doctest builder ignores them. Getting the name wrong is a build failure rather than a silent leak:make htmlruns with-W, so an unknown directive stops the build and the content does not render on the way out. A plain reST comment fails the other way round — dedent a single line and the prose is published with a clean build.Important
One review comment is actioned by deleting a rule rather than qualifying it, which needs a ruling.
lib/iris/AGENTS.mdbannedtry/conditional imports in a package__init__.py. That ban sat under Greppability, where it does not belong, since atry-wrapped import of a verbatim name greps perfectly well. It also contradicted the tree in four places:fileformats/__init__.py,io/__init__.pyandnetcdf/_attribute_handlers.pyall defer aniris_gribimport, andfileformats/zarr/__init__.pydoes the same forzarr. I removed the clause and folded the optional-dependency case into the surrounding rule, rather than adding a zarr-shaped exception to a rule four things already break.Where I would look first, in order of how little I trust myself:
zarr/saver.pyis the clearest example, where "the default mode isw-" stays and "a Zarr clobber is many non-atomic deletes" moves. If a judgement looks wrong, it is a one-line move to fix.io/format_picker.pyhad its marker withdrawn with no block added: its docstring is a usage tutorial throughout, and I had marked it on length rather than content.netcdf/saver.py,netcdf/ugrid_load.py,cf/_attribute_handlers.pyandio/__init__.pywere left alone for the same reason.tests/AGENTS.md, drawn at changes confined tolib/iris/tests/orchangelog/.Verified against a docs build that reads this branch, after a first attempt that did not
The suppression is confirmed by a clean
html-noplotbuild with the API pages. Every maintainer passage checked is absent fromgenerated/api: the import shadowing inzarr, the_CFSaverprivacy argument, the attribute-tracking trap incf.dataset, the non-atomic clobber inzarr.saver, the thin-loop description inzarr.loader. Every user-facing passage checked still renders: thew-default, the one-group-per-call rule, theattributesrouting rule, the optional dependency, the import-from-the-package instruction.The prose does remain in the
_modules/source listings, becausesphinx.ext.viewcodepublishes module source verbatim. The directive controls the rendered API page, not the published source.An earlier run of this check was worthless and is worth recording. The environment's editable install resolves
iristo a different checkout, soautomoduleread that tree's docstrings rather than this branch's, and the build proved nothing either way. Re-running withPYTHONPATHpointing at this branch'slibis what produced the result above.make doctestreports three failing documents —iris.experimental.geovista,iris.loadinganduser_manual/how_to/mesh_operations. A control run against the unmodified checkout fails on exactly the same three, so they pre-date this branch; the geovista one is an upstreampyvistarepr change. None is a module touched here.An AST comparison that ignores docstrings shows the code of all eighteen changed files is byte-identical to before.
All seven review comments, and what each did to the files
>>>example" carve-out is gone, and the requirement is on the Pre-Finish Checklist as asked.import *as its own rule__all__bullet, with no explanation attached.iris.fileformats.zarrbreaks the__init__.pyrulesda.zeros((10000, 10000), chunks=(100, 100))holds 10000 keys and[:100, :100]of it holds 10001, culled to 2 only at optimize time. The numbers stayed out of the file.lib/iristhat contain areturn, 95% have exactly one, so the old bullet argued against the surrounding code.Rejected: a zarr exception bullet, a compliance hook, and converting the human-authored NOTE comments
A separate bullet exempting
iris.fileformats.zarrwas written and then removed. It gave one module the weight of a rule, and zarr is not the exception.The conversion was originally deferred to a later change, to avoid conflicting with work in flight. It is now done here instead, because the module docstrings on
brownfieldare complete as of #7346 and leaving markers behind would seed the convention with a reminder rather than an example.A hook flagging
# NOTE:runs longer than three lines was considered, as the only mechanical signal that an agent skipped the block. It would fire on 34 existing sites, all human-authored and pre-dating the convention, so it was dropped.lib/iris/AGENTS.mdends at 300 lines, meeting the cap its own meta-instruction sets, which it did not before — the branch started at 303. The room came from tightening Module Docstrings Carry the Explanation, where three sentences were said twice: that inline comments scatter an argument and that a side Markdown file rots unseen are both Fast Rule 7, and that misspelling the directive fails the build is in the directive's own module docstring. Two structural savings were considered and dropped: the meta-instruction block is byte-identical in fourAGENTS.mdfiles and could become a pointer, but it is too important to demote; the Where Human and Agent Preferences Diverge table mostly restates rules stated elsewhere, but folding it is a change nobody asked for.pp-mo's review of the
.hooksadditions onbrownfieldis still to come, and will be actioned on this branch too.Checklist
Not applicable to this branch: a What's New entry, type hints, benchmarks and dependencies. Nothing here changes shipped behaviour, and the directive adds no package requirement.